import { BaseService, CoolCommException } from '@cool-midway/core';
import { Inject, Provide } from '@midwayjs/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import * as md5 from 'md5';
import { Equal, Repository } from 'typeorm';
import { v1 as uuid } from 'uuid';
import { PluginService } from '../../plugin/service/info';
import { UserInfoEntity } from '../entity/info';
import { UserSmsService } from './sms';
import { UserWxService } from './wx';
import { UserEmailService } from './email';
import { RegisterDTO } from '../dto/login';

/**
 * 用户信息
 */
@Provide()
export class UserInfoService extends BaseService {
  @InjectEntityModel(UserInfoEntity)
  userInfoEntity: Repository<UserInfoEntity>;

  @Inject()
  pluginService: PluginService;

  @Inject()
  userSmsService: UserSmsService;

  @Inject()
  userWxService: UserWxService;

  @Inject()
  userEmailService: UserEmailService;

  /**
   * 绑定小程序手机号
   * @param userId
   * @param code
   * @param encryptedData
   * @param iv
   */
  async miniPhone(userId: number, code: any, encryptedData: any, iv: any) {
    const phone = await this.userWxService.miniPhone(code, encryptedData, iv);
    await this.userInfoEntity.update({ id: Equal(userId) }, { phone });
    return phone;
  }

  /**
   * 获取用户信息
   * @param id
   * @returns
   */
  async person(id) {
    const info = await this.userInfoEntity.findOneBy({ id: Equal(id) });
    delete info.password;
    return info;
  }

  /**
   * 通过邮箱获取用户信息
   * @param email
   * @returns
   */
  async getUserByEmail(email: string) {
    console.log("email:", email);
    if (!email) {
      throw new CoolCommException('邮箱不能为空');
    }
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(email)) {
      throw new CoolCommException('邮箱格式不正确');
    }
    const info = await this.userInfoEntity.findOneBy({ email });
    if (info) {
      delete info.password;
    }
    return info;
  }

  /**
   * 注销
   * @param userId
   */
  async logoff(userId: number) {
    // 查询当前用户
    const user = await this.userInfoEntity.findOneBy({ id: userId });
    if (!user) return;

    console.log("user:", user);
    // 生成新用户名和手机号（如加上注销时间戳或uuid）
    const now = Date.now();
    const newUsername = user.username ? `deleted_${now}_${user.username}` : null;
    const newPhone = user.phone ? `deleted_${now}_${user.phone}` : null;

    await this.userInfoEntity.update(
      { id: userId },
      {
        status: 2,
        unionid: null,
        nickName: `已注销-00${userId}`,
        avatarUrl: null,
        phone: newPhone,
        username: newUsername,
      }
    );
  }

  /**
   * 更新用户信息
   * @param id
   * @param param
   * @returns
   */
  async updatePerson(id, param) {

    const info = await this.person(id);
    if (!info) throw new CoolCommException('用户不存在');
    try {
      // 修改了头像要重新处理
      if (param.avatarUrl && info.avatarUrl != param.avatarUrl) {
        /* guona:由于通过upload接口上传文件，故此处不需要再次下载上传，
           uni.uploadFile是转为文件上传设计，会自动处理文件流，无需开发者手动将文件转换为 Base64
           uni.request主要用于发送 HTTP 请求，其 data 参数通常用于传递 JSON、字符串或 URL 编码的数据，而不是文件流。如果尝试通过 uni.request 上传文件，必须先将文件转换为 Base64 或其他格式，这会增加内存开销，尤其是对于大文件
        */

        //guona:暂时不需要下载上传，目前通过upload接口上传文件
        // 如果是远程URL，下载后上传
        // const file = await this.pluginService.getInstance('upload');
        // param.avatarUrl = await file.downAndUpload(
        //   param.avatarUrl,
        //   uuid() + '.png'
        // );
        //判断是否是临时文件
        if (param.avatarUrl.startsWith('http://tmp/') || param.avatarUrl.startsWith('https://tmp/')) {
          // 如果是临时文件，直接上传
          throw new CoolCommException('请先上传图像');
        }
      }
    } catch (err) {
      throw new CoolCommException('图像上传失败: ' + err.message);
    }
    try {
      return await this.userInfoEntity.update({ id }, param);
    } catch (err) {
      throw new CoolCommException('更新失败，参数错误或者手机号已存在');
    }
  }

  /**
   * 更新密码
   * @param userId
   * @param password
   * @param 验证码
   */
  async updatePassword(params:RegisterDTO) {
    const { email, emailCode, password } = params;

    // 检查用户是否存在
    const user = await this.userInfoEntity.findOne({
      where: { email },
    });

    if (!user) {
      throw new CoolCommException('邮箱不存在');
    }

    // 验证邮箱验证码
    await this.userEmailService.verifyCode(email, emailCode, 1);

    // 更新密码
    await this.userInfoEntity.update(user.id, {
      password: md5(password),
    });

    return true;
  }

  /**
   * 绑定手机号
   * @param userId
   * @param phone
   * @param code
   */
  async bindPhone(userId, phone, code) {
    const check = await this.userSmsService.checkCode(phone, code);
    if (!check) {
      throw new CoolCommException('验证码错误');
    }
    await this.userInfoEntity.update({ id: userId }, { phone });
  }

  /**
   * 上传文件
   * @param file 
   * @returns 
   */
  async uploadFile(file) {
    try {
      const uploadPlugin = await this.pluginService.getInstance('upload');
      // 处理文件上传
      const uploadPath = await uploadPlugin.upload(file);

      return uploadPath;
    } catch (error) {
      throw new CoolCommException('上传失败: ' + error.message);
    }
  }

  /**
   * 注册
   */
  async register(params: any) {
    const { email, code, password } = params;

    // 验证邮箱验证码
    await this.userEmailService.verifyCode(email, code, 0);

    // 检查邮箱是否已注册
    const user = await this.userInfoEntity.findOne({
      where: { email },
    });

    if (user) {
      throw new CoolCommException('该邮箱已注册');
    }

    // 创建用户
    await this.userInfoEntity.save({
      email,
      password: md5(password),
    });

    return true;
  }

  /**
   * 微信用户绑定邮箱
   */
  async bindEmail(userId,  body: RegisterDTO ) {
    const { email, emailCode, password } = body;

    // 检查邮箱是否已注册
    const user = await this.userInfoEntity.findOne({
      where: { email, loginType: 2 }
    });
    if (user) {
      throw new CoolCommException('该邮箱已注册');
    }

    // 检查邮箱是否被微信用户绑定
    const bindUser = await this.userInfoEntity.findOne({
      where: { email, loginType: 0 }
    });
    if (bindUser) {
      throw new CoolCommException('该邮箱已被微信用户绑定');
    }

    // 验证邮箱验证码
    const check = await this.userEmailService.verifyCode(email, emailCode, 2);
    if (!check) {
      throw new CoolCommException('验证码错误');
    }

    // 绑定邮箱
    await this.userInfoEntity.update({ id: userId},{email, password:md5(password)} );

    return true;
  }

  /**
   * 微信用户解绑邮箱
   */
  async unBindEmail(userId) {

    // 检查邮箱是否已注册
    const user = await this.userInfoEntity.findOneBy({id:userId});
    if (!user) {
      throw new CoolCommException('未找到用户');
    }

    if(user.loginType !== 0){
      throw new CoolCommException('非微信用户不能解绑邮箱');
    }

    if(!user.email){
      throw new CoolCommException('微信用户未绑定邮箱');
    }

    // 解绑邮箱
    await this.userInfoEntity.update({ id: userId},{email:null, password:null} );

    return true;
  }
}
